package com.gbase8c.dmt.db.opengauss;

import com.gbase8c.dmt.db.object.UserObject;

import com.gbase8c.dmt.model.migration.dto.DataSourceDto;
import com.gbase8c.dmt.model.migration.dto.RoleDto;
import com.gbase8c.dmt.model.migration.dto.UserDto;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.dbutils.*;
import org.apache.commons.dbutils.handlers.ColumnListHandler;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@Slf4j
public class UserObjectImpl extends MetaImpl implements UserObject {

    public UserObjectImpl(DataSourceDto dataSourceDto) {
        super(dataSourceDto);
    }

    @Override
    public List<String> getNames(Map<String, Object> params) {
        List<String> names = Lists.newArrayList();
        return names;
    }

    @Override
    public UserDto get(String name, Map<String, Object> params) {
        return null;
    }

    @Override
    public UserDto convert(UserDto userDto, Map<String, Object> params) {
        if (userDto != null){
            //迁移状态置为是
            userDto.setConvertible(Boolean.TRUE);
        } else {
            userDto.setConvertible(Boolean.FALSE);
        }
        if (userDto.getConvertible()){
            userDto.setConvertMsg("已完成");
        } else {
            userDto.setConvertMsg("失败");
        }

        List<RoleDto> roleDtos = userDto.getRoleDtos();
        List<String> roles = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(roleDtos)){
            for (RoleDto roleDto:roleDtos){
                roles.add(roleDto.getName());
            }
        }
        userDto.setRoles(String.join(",",roles));

        return userDto;
    }

    @Override
    public String sql(UserDto userDto, Map<String, Object> params) {
        String existUsersql = "SELECT rolname from pg_roles;";
        QueryRunner qr = new QueryRunner(dataSource());
        BeanProcessor beanProcessor = new GenerousBeanProcessor();
        RowProcessor rowProcessor = new BasicRowProcessor(beanProcessor);

        boolean preserveCase = userDto.getTask().getMigrateConfig().isPreserveCase();
        List<String> existUser = null;
        try {
            existUser = qr.query(existUsersql, new ColumnListHandler<String>());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        StringBuilder sb = new StringBuilder();

        //用户名不存在，则创建
        if (!existUser.contains(userDto.getName().toLowerCase())){
            String userName = userDto.getName().toLowerCase();
            sb.append("CREATE USER ")
                    .append(wrap(userName, preserveCase))
                    .append(" with password \'gbase;123\'")
                    .append(";").append("\r\n");
        }

        //建系统权限
        UserDto.SysPrivDto sysPrivDto = userDto.getSysPrivDto();
        List<String> sysprivs = sysPrivilege2String(sysPrivDto,null);
        if (!sysprivs.equals("") && sysprivs != null){
            for (String syspriv:sysprivs){
                sb.append("Alter role " + wrap(userDto.getName(), preserveCase) + " with " + syspriv + ";").append("\r\n");
            }
        }

        //建库级权限，create权限单独处理
        if (userDto.getDatabasePrivDtos() != null){
            List<UserDto.DatabasePrivDto> databasePrivDtos = userDto.getDatabasePrivDtos();
            for (UserDto.DatabasePrivDto databasePrivDto:databasePrivDtos){
                if (databasePrivDto.getCreatePriv().equals("Y")){
                    //grant create on schema gaitest to role01;
                    sb.append("GRANT CREATE ON SCHEMA " + wrap(databasePrivDto.getSchemaName(), preserveCase) + " to " + userDto.getName()+";").append("\r\n");
                }
                String databaseprivs = databasePrivilege2String(databasePrivDto,null);
                if (!databaseprivs.equals("") && databaseprivs != null){
                    //grant select,insert on all tables in SCHEMA gaitest to user01;
                    //把第一个逗号去掉
                    sb.append("GRANT " + databaseprivs.substring(1,databaseprivs.length()-1) + " on all tables in schema "
                            + wrap(databasePrivDto.getSchemaName(), preserveCase) + " to " + userDto.getName() + " ;").append("\r\n");
                }
            }
        }

        //创建表级权限
        if (userDto.getTablePrivDtos()!=null){
            List<UserDto.TablePrivDto> tablePrivDtos = userDto.getTablePrivDtos();
            for (UserDto.TablePrivDto tablePrivDto:tablePrivDtos){
                String tableprivs = tablePrivilege2String(tablePrivDto,null);
                if (!tableprivs.equals("") && tableprivs != null){
                    //grant select,insert on gaitest.t_student to user01;
                    //把第一个逗号去掉
                    sb.append("GRANT " + tableprivs.substring(1,tableprivs.length()-1) + " on "
                            + wrap(tablePrivDto.getSchemaName(), preserveCase) + "."+tablePrivDto.getTableName() +" to " + userDto.getName() + " ;").append("\r\n");
                }
            }
        }

        //创建列级权限
        if (userDto.getColumnPrivDtos() != null){
            List<UserDto.ColumnPrivDto> columnPrivDtos = userDto.getColumnPrivDtos();
            for (UserDto.ColumnPrivDto columnPrivDto:columnPrivDtos){
                String columnprivs = columnPrivilege2String(columnPrivDto,null);
                if (!columnprivs.equals("") && columnprivs != null){
                    //grant insert,select(name) on gaitest.t_student to user01;
                    //把第一个逗号去掉
                    sb.append("GRANT " + columnprivs.substring(1,columnprivs.length()-1) + "("+ columnPrivDto.getColumnName()+") on "
                            + wrap(columnPrivDto.getSchemaName(), preserveCase) + "."+ columnPrivDto.getTableName() +" to " + userDto.getName() + " ;").append("\r\n");
                }
            }
        }
        log.info(String.valueOf(sb).toLowerCase());
        return sb.toString().toLowerCase();
    }

}
